﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EFDataModel
{
    public partial class EFWorktimeSetting
    {
        #region Static Functions
        /// <summary>
        /// Überprüft ob es sich um die gleichen Wochentage handelt.
        /// </summary>
        /// <param name="workingDay"></param>
        /// <param name="dayOfWeek"></param>
        /// <returns>TRUE->Gleiche Wochentage MO = Mo | FASLE->Unterschiedliche Wochentage Mo != Fr</returns>
        public static bool CheckDaysAreIdentical(EFWorkingDays workingDay, DayOfWeek dayOfWeek)
        {
            switch (workingDay)
            {
                //Wenn es sich um einen Samstag handelt, dann muss der Tag der Woche auch ein Samstag sein.
                case EFWorkingDays.Sat:
                    return dayOfWeek == DayOfWeek.Saturday;
                case EFWorkingDays.Sun:
                    return dayOfWeek == DayOfWeek.Sunday;
                case EFWorkingDays.Mon:
                    return dayOfWeek == DayOfWeek.Monday;
                case EFWorkingDays.Tue:
                    return dayOfWeek == DayOfWeek.Tuesday;
                case EFWorkingDays.Wed:
                    return dayOfWeek == DayOfWeek.Wednesday;
                case EFWorkingDays.Thu:
                    return dayOfWeek == DayOfWeek.Thursday;
                case EFWorkingDays.Fri:
                    return dayOfWeek == DayOfWeek.Friday;
            }

            return false;
        }

        /// <summary>
        /// Ermittelt aus einem DatetimeObjekt um welchen EFWorkingDay es sich handelt.
        /// </summary>
        /// <param name="date">Das Datum zu dem der passende EFWorkingDay ermittelt werden soll.</param>
        public static EFWorkingDays GetWorkingDayFromDateTime(DateTime date)
        {
            switch (date.DayOfWeek)
            {
                case DayOfWeek.Saturday:
                    return EFWorkingDays.Sat;
                case DayOfWeek.Sunday:
                    return EFWorkingDays.Sun;
                case DayOfWeek.Monday:
                    return EFWorkingDays.Mon;
                case DayOfWeek.Tuesday:
                    return EFWorkingDays.Tue;
                case DayOfWeek.Wednesday:
                    return EFWorkingDays.Wed;
                case DayOfWeek.Thursday:
                    return EFWorkingDays.Thu;
                case DayOfWeek.Friday:
                    return EFWorkingDays.Fri;
            }

            return EFWorkingDays.Mon;
        }
        #endregion

        /// <summary>
        /// Prüft ob der User überhaupt Arbeitstage ausgewählt hat.
        /// </summary>
        public bool HasWorkDaysSelected
        {
            get
            {
                //Nur wenn einer der Arbeitstage auch ausgewählt wurde, wurden die Tage festgelegt in denen gearbeitet werden soll.
                if (WorkingDays.Fri || WorkingDays.Mon || WorkingDays.Sat || WorkingDays.Sun || WorkingDays.Thu || WorkingDays.Tue || WorkingDays.Wed)
                {
                    return true;
                }

                return false;
            }
        }

        /// <summary>
        /// Gibt zurück ob der übergebene Arbeitstag auch ausgewählt ist.
        /// </summary>
        /// <param name="workingDay">Der Arbeitstag der überprüft werden soll, ob dieser bei uns auch ausgewählt ist.</param>
        /// <returns></returns>
        public bool HasWorkingDaySelected(EFWorkingDays workingDay)
        {
            switch (workingDay)
            {
                case EFWorkingDays.Sat:
                    return WorkingDays.Sat;
                case EFWorkingDays.Sun:
                    return WorkingDays.Sun;
                case EFWorkingDays.Mon:
                    return WorkingDays.Mon;
                case EFWorkingDays.Thu:
                    return WorkingDays.Thu;
                case EFWorkingDays.Wed:
                    return WorkingDays.Wed;
                case EFWorkingDays.Tue:
                    return WorkingDays.Tue;
                case EFWorkingDays.Fri:
                    return WorkingDays.Fri;
                case EFWorkingDays.None:
                    return false;
            }

            return false;
        }

        /// <summary>
        /// Gibt zurück ob der übergebene Arbeitstag im Datum auch ausgewählt ist.
        /// </summary>
        public bool HasWorkingDaySelected(DateTime date)
        {
            return HasWorkingDaySelected(GetWorkingDayFromDateTime(date));
        }

        /// <summary>
        /// Ermittelt den nächsten Arbeitstag für das übergebene Datum.
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public DateTime GetNextWorkingDay(DateTime date)
        {
            if (HasWorkDaysSelected)
            {
                NextWorkingDay(ref date);
            }

            return date;
        }

        /// <summary>
        /// Ermittelt den nächsten Arbeitstag für das übergebene Datum.
        /// </summary>
        /// <param name="date"></param>
        /// <returns></returns>
        public DateTime GetPrevWorkingDay(DateTime date)
        {
            if (HasWorkDaysSelected)
            {
                PrevWorkingDay(ref date);
            }

            return date;
        }

        private void NextWorkingDay(ref DateTime date)
        {
            date = date.AddDays(1);
            if (!HasWorkingDaySelected(date))
            {
                NextWorkingDay(ref date);
            }
        }

        private void PrevWorkingDay(ref DateTime date)
        {
            date = date.AddDays(-1);
            if (!HasWorkingDaySelected(date))
            {
                PrevWorkingDay(ref date);
            }
        }
    }
}
